package com.echovin.esb.gateway.filter;

import com.echovin.esb.gateway.constants.ErrorCode;
import com.echovin.esb.gateway.constants.OrderConstants;
import com.echovin.esb.gateway.exception.OpenException;
import com.echovin.esb.gateway.oauth2.handler.OAuth2AccessDecisionManager;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * token校验全局过滤器
 */
//@Component
public class TokenAuthorizeGlobalFilter implements GlobalFilter, Ordered {
    private static final String AUTHORIZE_TOKEN = "access_token";

    /**
     * 鉴权排除的url列表
     */
    private static final String[] excludedAuthUrls = {
            "/api/hello/**",
            "/esb/cdr/**",
    };
    @Autowired
    OAuth2AccessDecisionManager manager;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();
        String token = headers.getFirst(AUTHORIZE_TOKEN);
        String url = request.getURI().getPath();
        if (!StringUtils.isEmpty(headers.getFirst("SOAPAction"))) {
            // 说明是webservice，对其动作进行权限校验
            url = headers.getFirst("SOAPAction");
        }
        // 判断当前操作是否在列表中，无权限则返回提示页面
        boolean hasPermission = manager.checkPermission(token, url, excludedAuthUrls);
        if (!hasPermission) {
            throw new OpenException(ErrorCode.INVALID_TOKEN.getCode());
        }

        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return OrderConstants.TOKEN_AUTHORIZE;
    }
}
